# -*- coding: utf-8 -*-
"""
/***************************************************************************
 ModelePluieDebitDialog
                                 A QGIS plugin
 Outil de modélisation pluie-débit basé sur les modèles à réservoirs GR4J-GR2M de l'IRSTEA.

L'outil se décompose en plusieurs modules :
- définition de la couche des points de calcul,
- intégration de données d'entrée et prétraitement sur les points de calcul,
- construction de la table des paramètres du modèle aux points de calcul,
- lancement de simulations à partir d'une table des paramètres définis en chaque point de calcul,
- calcul de débits statistiques sur les débits simulés.
                             -------------------
        begin                : 2013-03-19
        copyright            : (c) 2014 by Alain Gauthier - Eaucéa
        email                : alain.gauthier@eaucea.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""
# profiling (décommenter pour activer avec le code correspondant à l'appel de la fonction étudiée)
#import pstats, cProfile


# modules système
import os
import ConfigParser
import sys
# modules QGIS
import qgis
from qgis.core import *
# modules GUI
from PyQt4 import QtCore, QtGui
from ui_modelepluiedebit import Ui_ModelePluieDebit
from ui_tabDonnees import Ui_widgetDonnees
from ui_tabModeleHydro import Ui_widgetModele
from ui_tabAnalyseExport import Ui_widgetAnalyse
from ui_tabCalculBV import Ui_widgetCalculBV
# modules traitement
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/calculBV")

import requete
from traitementDonneesEntree import *
from traitementModelePQ import *
from traitementResultat import *
import typeCritereNash

# constante de nom de fichier de configuration
__fichier_cfg__= os.path.join(os.getenv('HOME'),"modelepluiedebit.cfg")
__sectbv__='tabCalculBV'
__sectdonnees__='tabDonnees'
__sectmodele__='tabModele'

class ModelePluieDebitDialog(QtGui.QDialog):

    #--------------------------------------------------------------------------#

    def __init__(self):
        """
        Constructeur appelé par l'objet principal de l'extension (ModelePluieDebit)
        """
        QtGui.QDialog.__init__(self)
        # paramètres de l'application
        self.cheminBVCalcul = ""
        self.cheminChroniquesPluie = ""
        self.cheminDonneesPluie = ""
        self.dtPluie = 1 # unité jour
        self.cheminChroniquesEvapo = ""
        self.cheminDonneesEvapo = ""
        self.fichierStationCalage = ""
        self.fichierQmesure = ""
        self.critereEfficacite = typeCritereNash.listeCritereNash.index(typeCritereNash.__NASHLOGQ__)
        self.IDcoucheBVcalcul = -1
        # résultats de simulation
        self.resultatSimu=dict()
        self.statSimu=dict()
        # paramètres à optimiser pour les modèles GR2M et GR4J (X4 ne concerne que GR4J)
        self.paramOptim = ['X1','X2'] # les valeurs fixées sont lues dans le fichier des stations de calage
        # pas de temps fixé car les données sont mensuelles
        self.dtEvapo = 31 # unité jour
        # objets de traitement
        self.trtCalculBV = requete.requetes_qgis(qgis)
        self.trtDonneesEntree = TraitementDonneesEntree()
        self.trtModelePQ = TraitementModelePQ(self.cheminChroniquesPluie,
                                              self.cheminChroniquesEvapo,
                                              self.dtPluie,
                                              self.dtEvapo)
        self.trtResultat = TraitementResultat()

        # Set up the user interface from Designer.
        self.ui = Ui_ModelePluieDebit()
        self.ui.setupUi(self)

        # interface utilisateur par page (tab) : calcul des BV
        self.ui_tabBV = Ui_widgetCalculBV()
        self.ui_tabBV.setupUi(self.ui.tabDefPoints)
        self.ui_tabBV.buttonCalculerBV.released.connect(self.construireBVCalcul)
        self.ui_tabBV.pushButtonDossierCalc.released.connect(self.choisirCheminCalculBV)
        self.ui_tabBV.lineEditCheminCalcul.textChanged.connect(self.changerCheminBVCalcul)


        # interface utilisateur par page (tab) : données
        self.ui_tabDonnees = Ui_widgetDonnees()
        self.ui_tabDonnees.setupUi(self.ui.tabDonneesEntree)
        self.ui_tabDonnees.buttonRepChroniquesPluie.released.connect(self.choisirCheminChroniquesPluie)
        self.ui_tabDonnees.buttonRepDonneesPluie.released.connect(self.choisirCheminDonneesPluie)
        self.ui_tabDonnees.buttonConstruirePluie.released.connect(self.construireChroniquePluie)
        self.ui_tabDonnees.editPluvioChroniques.textChanged.connect(self.changerCheminChroniquePluie)
        self.ui_tabDonnees.editPluvioDonnees.textChanged.connect(self.changerCheminDonneePluie)

        self.ui_tabDonnees.buttonRepChroniquesEvapo.released.connect(self.choisirCheminChroniquesEvapo)
        self.ui_tabDonnees.buttonRepDonneesEvapo.released.connect(self.choisirCheminDonneesEvapo)
        self.ui_tabDonnees.buttonConstruireEvapo.released.connect(self.construireChroniqueEvapo)
        self.ui_tabDonnees.editEvapoChroniques.textChanged.connect(self.changerCheminChroniqueEvapo)
        self.ui_tabDonnees.editEvapoDonnees.textChanged.connect(self.changerCheminDonneeEvapo)

        # pour lier les combobox des couches vectorielles afin de sélectionner une seule couche de bv de calcul
        self.ui_tabDonnees.comboBoxCouchesPluie.currentIndexChanged.connect(self.ajusterComboBVEvapo)
        self.ui_tabDonnees.comboBoxCouchesEvapo.currentIndexChanged.connect(self.ajusterComboBVPluie)

        # interface utilisateur par page (tab) : modèle
        self.ui_tabModele = Ui_widgetModele()
        self.ui_tabModele.setupUi(self.ui.tabModelePQ)
        self.ui_tabModele.buttonFicStationsCalage.released.connect(self.choisirFichierStationCalage)
        self.ui_tabModele.editStationsCalage.textChanged.connect(self.changerFichierStationCalage)
        self.ui_tabModele.buttonFicMesure.released.connect(self.choisirFichierQmesure)
        self.ui_tabModele.editFichierMesure.textChanged.connect(self.changerFichierQmesure)
        self.ui_tabModele.radioButtonQ.released.connect(self.changerCritereEfficacite)
        self.ui_tabModele.radioButtonVQ.released.connect(self.changerCritereEfficacite)
        self.ui_tabModele.radioButtonLogQ.released.connect(self.changerCritereEfficacite)
        self.ui_tabModele.checkBoxX1.released.connect(self.changerParamOptim)
        self.ui_tabModele.checkBoxX2.released.connect(self.changerParamOptim)
        self.ui_tabModele.checkBoxX3.released.connect(self.changerParamOptim)
        self.ui_tabModele.buttonLancerCalage.released.connect(self.lancerCalage)
        self.ui_tabModele.buttonCalcul.released.connect(self.lancerCalcul)
        self.ui_tabModele.buttonCalculStat.released.connect(self.lancerCalculStat)

        # interface utilisateur par page (tag) : analyse et export des résultats
        self.ui_tabAnalyse = Ui_widgetAnalyse()
        self.ui_tabAnalyse.setupUi(self.ui.tabResultats)
        self.ui_tabAnalyse.buttonExportXGR.released.connect(self.exporterXGR)
        self.ui_tabAnalyse.buttonExportQsimu.released.connect(self.exporterQsimu)
        self.ui_tabAnalyse.buttonExportStat.released.connect(self.exporterStat)
        self.ui_tabAnalyse.buttonCreerAffichage.released.connect(self.creerAffichage)

    #--------------------------------------------------------------------------#

    def initialiser(self):
        """
        Initialisation des paramètres au moment où l'utilisateur à ouvert la fenêtre de dialogue
        du modèle pluie-débit
        """
        # liste des couches ouvertes
        listeCouches = QgsMapLayerRegistry.instance().mapLayers()
        nomCouches = listeCouches.keys()
        nomCouches.sort()

        # affichage des couches vectorielles seulement : noeuds de la BD Carthage
        if self.ui_tabBV.comboBoxCoucheNoeud.count()>0:
            self.ui_tabBV.comboBoxCoucheNoeud.clear()
        for id in nomCouches:
            couche = listeCouches[id]
            if couche.type()==0:
                self.ui_tabBV.comboBoxCoucheNoeud.addItem(couche.name(), id)
        # affichage des couches vectorielles seulement : tronçons de la BD Carthage
        if self.ui_tabBV.comboBoxCoucheTroncon.count()>0:
            self.ui_tabBV.comboBoxCoucheTroncon.clear()
        for id in nomCouches:
            couche = listeCouches[id]
            if couche.type()==0:
                self.ui_tabBV.comboBoxCoucheTroncon.addItem(couche.name(), id)
        # affichage des couches vectorielles seulement : sous-secteurs de la BD Carthage
        if self.ui_tabBV.comboBoxCoucheSousSecteur.count()>0:
            self.ui_tabBV.comboBoxCoucheSousSecteur.clear()
        for id in nomCouches:
            couche = listeCouches[id]
            if couche.type()==0:
                self.ui_tabBV.comboBoxCoucheSousSecteur.addItem(couche.name(), id)
        # affichage des couches vectorielles seulement : secteurs de la BD Carthage
        if self.ui_tabBV.comboBoxCoucheSecteur.count()>0:
            self.ui_tabBV.comboBoxCoucheSecteur.clear()
        for id in nomCouches:
            couche = listeCouches[id]
            if couche.type()==0:
                self.ui_tabBV.comboBoxCoucheSecteur.addItem(couche.name(), id)
        # affichage des couches vectorielles seulement : bv élémentaires de la BD Carthage
        if self.ui_tabBV.comboBoxCoucheBVElem.count()>0:
            self.ui_tabBV.comboBoxCoucheBVElem.clear()
        for id in nomCouches:
            couche = listeCouches[id]
            if couche.type()==0:
                self.ui_tabBV.comboBoxCoucheBVElem.addItem(couche.name(), id)

        # affichage des couches vectorielles seulement : bv en entrée pour construire les chroniques
        if self.ui_tabDonnees.comboBoxCouchesPluie.count()>0:
            self.ui_tabDonnees.comboBoxCouchesPluie.clear()
        for id in nomCouches:
            couche = listeCouches[id]
            if couche.type()==0:
                self.ui_tabDonnees.comboBoxCouchesPluie.addItem(couche.name(), id)
        # affichage des couches vectorielles seulement : bv en entrée pour construire les chroniques
        if self.ui_tabDonnees.comboBoxCouchesEvapo.count()>0:
            self.ui_tabDonnees.comboBoxCouchesEvapo.clear()
        for id in nomCouches:
            couche = listeCouches[id]
            if couche.type()==0:
                self.ui_tabDonnees.comboBoxCouchesEvapo.addItem(couche.name(), id)

        # paramètres à optimiser par défaut dans l'onglet de lancement du modèle
        self.MAJCheckBoxParamOptim(self.paramOptim)
        # critère d'efficacité par défaut dans l'onglet de lancement du modèle
        self.MAJRadioBoutonCritereEfficacite(self.critereEfficacite)

        # lecture du fichier de configuration s'il existe
        self.lirefichiercfg()

        # barre de progression
        self.ui.progressBar.setMinimum(0)
        self.ui.progressBar.setMaximum(100)
        self.ui.progressBar.setValue(0)
        # objets utilisant la barre de progression
        self.trtDonneesEntree.setprogressBar(self.ui.progressBar)
        self.trtModelePQ.setprogressBar(self.ui.progressBar)
        self.trtCalculBV.setprogressBar(self.ui.progressBar)

    #--------------------------------------------------------------------------#

    def finaliser(self):
        """
        méthode appelée fermeture de Morph'Eau
        """
        # enregistrement des données dans le fichier de configuration
        self.ecrirefichiercfg()

    #--------------------------------------------------------------------------#

    def lirefichiercfg(self):
        """
        lecture des données du fichier de config pour l'interface utilisateur
        Abandon de la lecture en cas d'erreur
        """
        config = ConfigParser.RawConfigParser()
        try:
            config.read(__fichier_cfg__)
            # tab points de calcul
            chemin = config.get(__sectbv__,'destinationBVCalcul')
            self.ui_tabBV.lineEditCheminCalcul.setText(chemin)
            # tab données
            chemin = config.get(__sectdonnees__, 'chroniquesPluies')
            self.ui_tabDonnees.editPluvioChroniques.setText(chemin)
            chemin = config.get(__sectdonnees__, 'chroniquesEvapo')
            self.ui_tabDonnees.editEvapoChroniques.setText(chemin)
            self.dtPluie = config.getint(__sectdonnees__, 'dtPluie')
            self.ui_tabDonnees.spinBoxDTPluie.setValue(self.dtPluie)
            # tab modèle
            param = config.get(__sectmodele__, 'fichierCalage')
            self.ui_tabModele.editStationsCalage.setText(param)
            param = config.get(__sectmodele__, 'fichierQMesure')
            self.ui_tabModele.editFichierMesure.setText(param)
        except:
            pass

    #--------------------------------------------------------------------------#

    def ecrirefichiercfg(self):
        """
        Ecriture des données du fichier de config pour l'interface utilisateur
        Abandon de l'écriture en cas d'erreur
        """
        config = ConfigParser.RawConfigParser()
        try:
            # tab points de calcul
            config.add_section(__sectbv__)
            config.set(__sectbv__,'destinationBVCalcul',self.cheminBVCalcul)
            # tab données
            config.add_section(__sectdonnees__)
            config.set(__sectdonnees__,'chroniquesPluies',self.cheminChroniquesPluie)
            config.set(__sectdonnees__,'chroniquesEvapo',self.cheminChroniquesEvapo)
            config.set(__sectdonnees__,'dtPluie',str(self.dtPluie))
            # tab modèle
            config.add_section(__sectmodele__)
            config.set(__sectmodele__,'fichierCalage',self.fichierStationCalage)
            config.set(__sectmodele__,'fichierQMesure',self.fichierQmesure)
        finally:
            # écriture dans le fichier
            fid = open(__fichier_cfg__,'w')
            config.write(fid)
            fid.close()

    #--------------------------------------------------------------------------#

    def construireBVCalcul(self):
        """
        méthode appelée sur signal "released()" du bouton de construction des BV de calcul
        """
        # condition pour pouvoir continuer
        if len(self.ui_tabBV.comboBoxCoucheNoeud) == 0:
            QtGui.QMessageBox.information(None,QtGui.QApplication.translate('widgetDonnees','Information'), \
                QtGui.QApplication.translate('widgetDonnees',u'Aucune couche vectorielle ouverte'))
            return

        # préparation des données pour le traitement
        IDcoucheNoeud = self.ui_tabBV.comboBoxCoucheNoeud.itemData(self.ui_tabBV.comboBoxCoucheNoeud.currentIndex())
        IDcoucheTroncon = self.ui_tabBV.comboBoxCoucheTroncon.itemData(self.ui_tabBV.comboBoxCoucheTroncon.currentIndex())
        IDcoucheSousSecteur = self.ui_tabBV.comboBoxCoucheSousSecteur.itemData(self.ui_tabBV.comboBoxCoucheSousSecteur.currentIndex())
        IDcoucheSecteur = self.ui_tabBV.comboBoxCoucheSecteur.itemData(self.ui_tabBV.comboBoxCoucheSecteur.currentIndex())
        IDcoucheBVElem = self.ui_tabBV.comboBoxCoucheBVElem.itemData(self.ui_tabBV.comboBoxCoucheBVElem.currentIndex())

        # appel du traitement
        self.trtCalculBV.set_coucheNoeud(IDcoucheNoeud)
        self.trtCalculBV.set_coucheTroncon(IDcoucheTroncon)
        self.trtCalculBV.set_coucheSousSecteur(IDcoucheSousSecteur)
        self.trtCalculBV.set_coucheSecteur(IDcoucheSecteur)
        self.trtCalculBV.set_coucheBVElem(IDcoucheBVElem)

        # profiling (pouvant être lancé en debug)
        # analyse du résultat avec le script :
        # C:\Projets\dev\Guyane_PQR\ModelePluieDebit\calculBV\affichage_fic_profile.py
##        fichierprofile = "C:/Projets/dev/Profile_calculBVamont.prof"
##        cProfile.runctx("self.trtCalculBV.sousBVAmontParNoeud(self.cheminBVCalcul)",
##                        globals(),
##                        locals(),
##                        fichierprofile)

        # appel normal sans profiling
        self.trtCalculBV.sousBVAmontParNoeud(self.cheminBVCalcul)

    #--------------------------------------------------------------------------#

    def choisirCheminCalculBV(self):
        """
        méthode appelée sur signal "released()" du bouton de choix du chemin de sauvegarde des points de calcul
        """
        chemin = QtGui.QFileDialog.getExistingDirectory(self,
                                                        u'Choisir un dossier de sauvegarde des BV calculés',
                                                        os.getenv('HOME'),
                                                        QtGui.QFileDialog.ShowDirsOnly)
        if not chemin:
            return
        self.ui_tabBV.lineEditCheminCalcul.setText(chemin)
        self.cheminBVCalcul = chemin
        self.ecrirefichiercfg()

    #--------------------------------------------------------------------------#

    def choisirCheminChroniquesPluie(self):
        """
        méthode appelée sur signal "released()" du bouton de choix du chemin des chroniques
        """
        chemin = QtGui.QFileDialog.getExistingDirectory(self,
                                                        u'Choisir un dossier',
                                                        os.getenv('HOME'),
                                                        QtGui.QFileDialog.ShowDirsOnly)
        if not chemin:
            return
        self.ui_tabDonnees.editPluvioChroniques.setText(chemin)
        self.cheminChroniquesPluie = chemin
        self.ecrirefichiercfg()

    #--------------------------------------------------------------------------#

    def choisirCheminChroniquesEvapo(self):
        """
        méthode appelée sur signal "released()" du bouton de choix du chemin des chroniques
        """
        chemin = QtGui.QFileDialog.getExistingDirectory(self,
                                                        u'Choisir un dossier',
                                                        os.getenv('HOME'),
                                                        QtGui.QFileDialog.ShowDirsOnly)
        if not chemin:
            return
        self.ui_tabDonnees.editEvapoChroniques.setText(chemin)
        self.cheminChroniquesEvapo = chemin
        self.ecrirefichiercfg()

    #--------------------------------------------------------------------------#

    def changerCheminBVCalcul(self):
        """
        méthode appelée sur signal "textChanged" de l'objet d'édition du chemin de sauvegarde des points de calcul
        """
        # mise à jour du chemin saisi
        self.cheminBVCalcul = self.ui_tabBV.lineEditCheminCalcul.text()

    #--------------------------------------------------------------------------#

    def changerCheminChroniquePluie(self):
        """
        méthode appelée sur signal "textChanged" de l'objet d'édition de texte
        """
        # mise à jour du chemin saisi
        self.cheminChroniquesPluie = self.ui_tabDonnees.editPluvioChroniques.text()

    #--------------------------------------------------------------------------#

    def changerCheminChroniqueEvapo(self):
        """
        méthode appelée sur signal "textChanged" de l'objet d'édition de texte
        """
        # mise à jour du chemin saisi
        self.cheminChroniquesEvapo = self.ui_tabDonnees.editEvapoChroniques.text()

    #--------------------------------------------------------------------------#

    def changerCheminDonneePluie(self):
        """
        méthode appelée sur signal "textChanged" de l'objet d'édition de texte
        """
        # mise à jour du chemin saisi
        self.cheminDonneesPluie = self.ui_tabDonnees.editPluvioDonnees.text()

    #--------------------------------------------------------------------------#

    def changerCheminDonneeEvapo(self):
        """
        méthode appelée sur signal "textChanged" de l'objet d'édition de texte
        """
        # mise à jour du chemin saisi
        self.cheminDonneesEvapo = self.ui_tabDonnees.editEvapoDonnees.text()

    #--------------------------------------------------------------------------#

    def choisirCheminDonneesPluie(self):
        """
        méthode appelée sur signal "released()" du bouton de choix du chemin des donnees de pluie
        """
        chemin = QtGui.QFileDialog.getExistingDirectory(self,
                                                        u'Choisir un dossier',
                                                        os.getenv('HOME'),
                                                        QtGui.QFileDialog.ShowDirsOnly)
        if not chemin:
            return
        self.ui_tabDonnees.editPluvioDonnees.setText(chemin)
        self.cheminDonneesPluie = chemin

    #--------------------------------------------------------------------------#

    def choisirCheminDonneesEvapo(self):
        """
        méthode appelée sur signal "released()" du bouton de choix du chemin des donnees de pluie
        """
        chemin = QtGui.QFileDialog.getExistingDirectory(self,
                                                        u'Choisir un dossier',
                                                        os.getenv('HOME'),
                                                        QtGui.QFileDialog.ShowDirsOnly)
        if not chemin:
            return
        self.ui_tabDonnees.editEvapoDonnees.setText(chemin)
        self.cheminDonneesEvapo = chemin

    #--------------------------------------------------------------------------#

    def construireChroniquePluie(self):
        """
        méthode appelée sur signal "released()" du bouton de construction des chroniques de pluie
        """
        # condition pour pouvoir continuer
        if len(self.ui_tabDonnees.comboBoxCouchesPluie) == 0:
            QtGui.QMessageBox.information(None,QtGui.QApplication.translate('widgetDonnees','Information'), \
                QtGui.QApplication.translate('widgetDonnees',u'Aucune couche vectorielle ouverte'))
            return

        # préparation des données pour le traitement
        self.IDcoucheBVcalcul = self.ui_tabDonnees.comboBoxCouchesPluie.itemData(self.ui_tabDonnees.comboBoxCouchesPluie.currentIndex())
        self.dtPluie = self.ui_tabDonnees.spinBoxDTPluie.value()

        # vérification des données
        if self.IDcoucheBVcalcul<0:
            QtGui.QMessageBox.information(None,QtGui.QApplication.translate('widgetDonnees','Information'), \
                QtGui.QApplication.translate('widgetDonnees',u'Il faut sélectionner la couche des BV de calcul'))
            return

        if self.cheminDonneesPluie =='':
            QtGui.QMessageBox.information(None,QtGui.QApplication.translate('widgetDonnees','Information'), \
                QtGui.QApplication.translate('widgetDonnees',u'Il faut sélectionner le dossier des données pluviométriques'))
            return

        # profiling
##        cProfile.runctx("self.trtDonneesEntree.calculerChroniques(self.IDcoucheBVcalcul,self.cheminDonneesPluie,self.dtPluie,codePluie)",
##                        globals(),
##                        locals(),
##                        "C:/Projets/dev/Profile_chroniques.prof")
        # appel du traitement normal
        chemin = self.trtDonneesEntree.calculerChroniques(self.IDcoucheBVcalcul,self.cheminDonneesPluie,self.dtPluie,codePluie)
        self.ui_tabDonnees.editPluvioChroniques.setText(chemin)

    #--------------------------------------------------------------------------#

    def construireChroniqueEvapo(self):
        """
        méthode appelée sur signal "released()" du bouton de construction des chroniques d'évapotranspiration
        """
        # condition pour pouvoir continuer
        if len(self.ui_tabDonnees.comboBoxCouchesEvapo) == 0:
            QtGui.QMessageBox.information(None,QtGui.QApplication.translate('widgetDonnees','Information'), \
                QtGui.QApplication.translate('widgetDonnees',u'Aucune couche vectorielle ouverte'))
            return

        # préparation des données pour le traitement
        self.IDcoucheBVcalcul = self.ui_tabDonnees.comboBoxCouchesEvapo.itemData(self.ui_tabDonnees.comboBoxCouchesEvapo.currentIndex())

        # vérification des données
        if self.IDcoucheBVcalcul<0:
            QtGui.QMessageBox.information(None,QtGui.QApplication.translate('widgetDonnees','Information'), \
                QtGui.QApplication.translate('widgetDonnees',u'Il faut sélectionner la couche des BV de calcul'))
            return

        if self.cheminDonneesEvapo =='':
            QtGui.QMessageBox.information(None,QtGui.QApplication.translate('widgetDonnees','Information'), \
                QtGui.QApplication.translate('widgetDonnees',u"Il faut sélectionner le dossier des données d'évapotranspiration"))
            return

        # appel du traitement
        chemin = self.trtDonneesEntree.calculerChroniques(self.IDcoucheBVcalcul,self.cheminDonneesEvapo,self.dtEvapo,codeEvapo)
        self.ui_tabDonnees.editEvapoChroniques.setText(chemin)

    #--------------------------------------------------------------------------#

    def ajusterComboBVEvapo(self,aindex):
        """
        appelé sur le signal currentIndexChanged(int)
        """
        self.ajusterAutreComboBV(self.ui_tabDonnees.comboBoxCouchesEvapo,aindex)

    def ajusterComboBVPluie(self,aindex):
        """
        appelé sur le signal currentIndexChanged(int)
        """
        self.ajusterAutreComboBV(self.ui_tabDonnees.comboBoxCouchesPluie,aindex)

    def ajusterAutreComboBV(self,aComboBox, aindex):
        """
        pour mettre à jour l'index aindex à aComboBox si nécessaire
        """
        if not aindex==aComboBox.currentIndex():
            aComboBox.setCurrentIndex(aindex)

    #--------------------------------------------------------------------------#

    def choisirFichierStationCalage(self):
        """
        méthode appelée sur signal "released()" du bouton de choix du fichier contenant les stations de calage
        """

        # ouverture du fichier
        fichierCalage = QtGui.QFileDialog.getOpenFileName(self,
                                                          u'Ouvrir le fichier de stations de calage',
                                                          os.getenv('HOME'),
                                                          self.tr('fichiers CSV (*.CSV)'))

        # mise à jour du composant d'affichage
        self.ui_tabModele.editStationsCalage.setText(fichierCalage)
        self.ecrirefichiercfg()

    #--------------------------------------------------------------------------#

    def changerFichierStationCalage(self):
        """
        méthode appelée sur signal "textChanged" de l'objet d'édition de texte
        """
        # mise à jour du chemin saisi
        self.fichierStationCalage = self.ui_tabModele.editStationsCalage.text()

    #--------------------------------------------------------------------------#

    def choisirFichierQmesure(self):
        """
        méthode appelée sur signal "released()" du bouton de choix du fichier contenant les débits mesurés
        """

        # ouverture du fichier
        fichierQmesure = QtGui.QFileDialog.getOpenFileName(self,
                                                           u'Ouvrir le fichier des mesures de débits',
                                                           os.getenv('HOME'),
                                                           self.tr('fichiers CSV (*.CSV)'))

        # mise à jour du composant d'affichage
        self.ui_tabModele.editFichierMesure.setText(fichierQmesure)
        self.ecrirefichiercfg()

    #--------------------------------------------------------------------------#

    def changerFichierQmesure(self):
        """
        méthode appelée sur signal "textChanged" de l'objet d'édition de texte
        """
        # mise à jour du chemin saisi
        self.fichierQmesure = self.ui_tabModele.editFichierMesure.text()

    #--------------------------------------------------------------------------#

    def changerCritereEfficacite(self):
        """
        méthode appelée sur le signal "released" des radio boutons de choix du critère d'efficacité
        """

        # mise à jour du critère d'efficacité
        if self.ui_tabModele.radioButtonQ.isChecked():
            self.critereEfficacite = typeCritereNash.listeCritereNash.index(typeCritereNash.__NASHQ__)
        if self.ui_tabModele.radioButtonVQ.isChecked():
            self.critereEfficacite = typeCritereNash.listeCritereNash.index(typeCritereNash.__NASHVQ__)
        if self.ui_tabModele.radioButtonLogQ.isChecked():
            self.critereEfficacite = typeCritereNash.listeCritereNash.index(typeCritereNash.__NASHLOGQ__)

    #--------------------------------------------------------------------------#

    def changerParamOptim(self):
        """
        méthode appelée sur le signal "released" des checkBoxs de choix des paramètres à optimiser
        """
        # mise à jour des paramètres à optimiser
        self.paramOptim = []
        if self.ui_tabModele.checkBoxX1.isChecked():
            self.paramOptim.append('X1')
        if self.ui_tabModele.checkBoxX2.isChecked():
            self.paramOptim.append('X2')
        if self.ui_tabModele.checkBoxX3.isChecked():
            self.paramOptim.append('X3')

    #--------------------------------------------------------------------------#

    def MAJCheckBoxParamOptim(self,AparamOptim):
        """
        mise à jour des checkboxs selon la valeur AparamOptim
        """
        if 'X1' in AparamOptim:
            self.ui_tabModele.checkBoxX1.setChecked(True)
        if 'X2' in AparamOptim:
            self.ui_tabModele.checkBoxX2.setChecked(True)
        if 'X3' in AparamOptim:
            self.ui_tabModele.checkBoxX3.setChecked(True)

    #--------------------------------------------------------------------------#

    def MAJRadioBoutonCritereEfficacite(self,AindexCritere):
        """
        mise à jour des radio-boutons de choix du critère d'efficacité selon la valeur AindexCritere
        """
        if AindexCritere == typeCritereNash.listeCritereNash.index(typeCritereNash.__NASHQ__):
            self.ui_tabModele.radioButtonQ.setChecked(True)
        if AindexCritere == typeCritereNash.listeCritereNash.index(typeCritereNash.__NASHVQ__):
            self.ui_tabModele.radioButtonVQ.setChecked(True)
        if AindexCritere == typeCritereNash.listeCritereNash.index(typeCritereNash.__NASHLOGQ__):
            self.ui_tabModele.radioButtonLogQ.setChecked(True)

    #--------------------------------------------------------------------------#

    def lancerCalage(self):
        """
        Lancement du calage avec les paramètres fixés
        Cette méthode ne fonctionne que si les paramètres du modèle sont bien tous définis c'est à dire :
            - BV chargé avec les chroniques de pluie et Evapotranspiration
            - Pas de temps cohérent avec celui des chroniques
            - Fichier de calage défini
            - Fichier de Q mesuré défini
            - Critère d'efficacité défini
        """

        # écriture du fichier de configuration
        self.dtPluie = self.ui_tabDonnees.spinBoxDTPluie.value()
        self.ecrirefichiercfg()

        # mise à jour des données utilisateur
        self.trtModelePQ.mettreAJourDonnees(self.cheminChroniquesPluie,
                                            self.cheminChroniquesEvapo,
                                            self.dtPluie,
                                            self.dtEvapo)
        # appel de la méthode de calage :
        self.trtModelePQ.lancerCalage(self.fichierStationCalage,
                                      self.fichierQmesure,
                                      self.critereEfficacite,
                                      self.paramOptim)

        # mise à jour graphique
        self.mettreAJourInterfaceAnalyse()

    #--------------------------------------------------------------------------#

    def lancerCalcul(self):
        """
        Lancement du calcul de chroniques de débit pour le modèle calé au niveau régional sur des BV sélectionné
        par l'utilisateur dans la couche des BV (cf tab données)
        La valeur des paramètres du modèle GR est calculée selon la méthode de régionalisation
        """

        # vérification des données
        self.IDcoucheBVcalcul = self.ui_tabDonnees.comboBoxCouchesPluie.itemData(self.ui_tabDonnees.comboBoxCouchesPluie.currentIndex())
        if self.IDcoucheBVcalcul<0:
            QtGui.QMessageBox.information(None,QtGui.QApplication.translate('widgetDonnees','Information'), \
                QtGui.QApplication.translate('widgetDonnees',
                                             u"Il faut sélectionner la couche des BV de calcul dans l'onglet 'données'"))
            return

        if len(self.trtModelePQ.resultatOptim.keys()) == 0:
            QtGui.QMessageBox.information(None,QtGui.QApplication.translate('widgetDonnees','Information'), \
                QtGui.QApplication.translate('widgetDonnees',
                                             u"Le calage du modèle n'a pas été fait"))
            return

        # mise à jour des données utilisateur
        self.trtModelePQ.mettreAJourDonnees(self.cheminChroniquesPluie,
                                            self.cheminChroniquesEvapo,
                                            self.dtPluie,
                                            self.dtEvapo)
        # lancement de la simulation
        self.resultatSimu=self.trtModelePQ.lancerSimulation(self.IDcoucheBVcalcul)

        # mise à jour graphique
        self.mettreAJourInterfaceAnalyse()

    #--------------------------------------------------------------------------#

    def lancerCalculStat(self):
        """
        Lancement du calcul de chroniques de débit pour le modèle calé au niveau régional sur des BV sélectionné
        par l'utilisateur dans la couche des BV (cf tab données)
        La valeur des paramètres du modèle GR est calculée selon la méthode de régionalisation
        """

        # vérification des données
        if len(self.resultatSimu.keys())==0:
            QtGui.QMessageBox.information(None,QtGui.QApplication.translate('widgetDonnees','Information'), \
                QtGui.QApplication.translate('widgetDonnees',
                                             u"Il faut lancer le calcul avant de faire des statistiques"))
            return

        # mise à jour des données utilisateur
        self.trtModelePQ.mettreAJourDonnees(self.cheminChroniquesPluie,
                                            self.cheminChroniquesEvapo,
                                            self.dtPluie,
                                            self.dtEvapo)
        # lancement de la simulation
        self.statSimu=self.trtModelePQ.calculStat(self.resultatSimu)

        # mise à jour graphique
        self.mettreAJourInterfaceAnalyse()

    #--------------------------------------------------------------------------#

    def exporterXGR(self):
        """
        Export des paramètres du modèle GR dans deux fichiers CSV :
            - ceux des stations de mesure
            - ceux des BV dont la simulation a été faite
        """
        # choix du dossier d'export
        chemin = QtGui.QFileDialog.getExistingDirectory(self,
                                                        u'Choisir un dossier pour exporter les données',
                                                        os.getenv('HOME'),
                                                        QtGui.QFileDialog.ShowDirsOnly)
        if not chemin:
            return
        chemin = chemin
        # export des paramètres de calage du modèle
        self.trtResultat.exporter_XGR_station(chemin,
                                              self.trtModelePQ.dicoStations,
                                              self.trtModelePQ.resultatOptim,
                                              self.trtModelePQ.critereOptim)

        # export des paramètres pour les BV simulés
        self.trtResultat.exporter_XGR_simu(chemin,self.resultatSimu)

    #--------------------------------------------------------------------------#

    def exporterQsimu(self):
        """
        Export des chroniques de débits simulés dans un fichier CSV
        """
        # choix du dossier d'export
        chemin = QtGui.QFileDialog.getExistingDirectory(self,
                                                        u'Choisir un dossier pour exporter les chroniques',
                                                        os.getenv('HOME'),
                                                        QtGui.QFileDialog.ShowDirsOnly)
        if not chemin:
            return
        # export des chroniques simulées par le modèle
        self.trtResultat.exporter_Qsimu(chemin, self.resultatSimu)

    #--------------------------------------------------------------------------#

    def exporterStat(self):
        """
        Export des statistiques calculées sur mes chroniques de débits simulés dans un fichier CSV
        """
        # choix du dossier d'export
        chemin = QtGui.QFileDialog.getExistingDirectory(self,
                                                        u'Choisir un dossier pour exporter les statistiques',
                                                        os.getenv('HOME'),
                                                        QtGui.QFileDialog.ShowDirsOnly)
        if not chemin:
            return
        # export des chroniques simulées par le modèle
        self.trtResultat.exporter_Stats(chemin, self.statSimu, self.resultatSimu)

    #--------------------------------------------------------------------------#

    def mettreAJourInterfaceAnalyse(self):
        """
        mise à jour des données pour l'analyse et l'export des résultats. A faire après chaque simulation
        """
        # résultats de simulation
        self.ui_tabAnalyse.comboBoxID_BV.clear()
        for id_bv in self.resultatSimu:
            self.ui_tabAnalyse.comboBoxID_BV.addItem(id_bv, id_bv)

        # résultats de calage
        self.ui_tabAnalyse.comboBoxID_Station.clear()
        for id_station in self.trtModelePQ.dicoStations:
            self.ui_tabAnalyse.comboBoxID_Station.addItem(self.trtModelePQ.dicoStations[id_station]['nom_station'],
                                                          id_station)

    #--------------------------------------------------------------------------#

    def creerAffichage(self):
        """
        création de l'affichage d'un résultat de simulation.
        """
        # résultat sélectionné
        id_bv =self.ui_tabAnalyse.comboBoxID_BV.itemData(self.ui_tabAnalyse.comboBoxID_BV.currentIndex())
        id_bv=str(id_bv)
        # options d'affichage
        optionP = self.ui_tabAnalyse.checkBoxPluie.isChecked()
        optionE = self.ui_tabAnalyse.checkBoxEvapo.isChecked()
        optionQs = self.ui_tabAnalyse.checkBoxQsimu.isChecked()
        optionQm = self.ui_tabAnalyse.checkBoxQmesu.isChecked()
        id_station='0'
        if optionQm:
            id_station=self.ui_tabAnalyse.comboBoxID_Station.itemData(self.ui_tabAnalyse.comboBoxID_Station.currentIndex())
            id_station=str(id_station)

        # création de l'affichage
        optionsAff=(optionP,optionE,optionQs,optionQm)
        self.trtResultat.creerAffichage(id_bv,
                                        id_station,
                                        optionsAff,
                                        self.resultatSimu,
                                        self.trtModelePQ.chroniquesQmesure)

#------------------------------------------------------------------------------#
#------------------------------------------------------------------------------#
